package campus.aiit.ssl.service;

import campus.aiit.ssl.dao.BlockDao;
import campus.aiit.ssl.dao.DeviceDao;
import campus.aiit.ssl.dao.UserDao;
import campus.aiit.ssl.domain.model.Block;
import campus.aiit.ssl.domain.model.Device;
import campus.aiit.ssl.domain.model.User;
import campus.aiit.ssl.manage.custom.dao.DaoProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author ihaokun
 * @date 2019/12/31 16:51
 */
@Service
public class UserService {
  private UserDao userDao;
  private DeviceDao deviceDao;
  private BlockDao blockDao;

  @Autowired
  public UserService(UserDao userDao, DeviceDao deviceDao, BlockDao blockDao) {
    this.userDao = new DaoProxy<UserDao>().getProxy(userDao);
    this.deviceDao = deviceDao;
    this.blockDao = blockDao;
  }

  @Transactional
  public boolean add(User user) throws AlreadyException {
      if(user.getRoleId()!=3){
          //检验区域块是否被其它用户管理
          for (long blockId: user.getBlockIds()) {
              if (blockDao.selectByPrimaryKey(blockId).getUserId()!=null && !blockDao.selectByPrimaryKey(blockId).getUserId().equals(user.getId())){
                  throw new AlreadyException("该区域块为其他用户管理");
              }
          }
          //assign device
          assignBlocks(user);
      }
      //add user
      userDao.insertSelective(user);
    return true;
  }

  @Transactional
  public boolean modify(User user) throws AlreadyException {
//    for (long blockId: user.getBlockIds()) {
//      if (blockDao.selectByPrimaryKey(blockId).getUserId()!=null && !blockDao.selectByPrimaryKey(blockId).getUserId().equals(user.getId())){
//        throw new AlreadyException("该区域块为其他用户管理");
//      }
//    }
    assignBlocks(user);
    userDao.updateByPrimaryKeySelective(user);
    return true;
  }

  private void assignBlocks(User user) throws AlreadyException {
    blockDao.updateUserNull(user.getId());
    deviceDao.updateUserNull(user.getId());
    for (long blockId: user.getBlockIds()) {
        blockDao.updateUserByPrimaryKey(user.getId(), blockId);
        deviceDao.updateUserByBlockUserId(blockId, user.getId());
    }
  }

//  @Transactional
//  public boolean modify(User user) throws AlreadyException {
//    deviceDao.updateUserNull(user.getId());
//    assignDevices(user);
//    userDao.updateByPrimaryKeySelective(user);
//    return true;
//  }
//
//  private void assignDevices(User user) throws AlreadyException {
//    for (long deviceId : user.getDeviceIds()) {
//      if (deviceDao.selectByPrimaryKey(deviceId).getUserId() != null) {
//        throw new AlreadyException("该设备为其他用户所有");
//      }
//      deviceDao.updateUserByPrimaryKey(user.getId(), deviceId);
//    }
//  }

  public List<User> list(byte roleId){
    return userDao.selectAll(roleId);
  }

  @Transactional
  public boolean remove(String userId){
    deviceDao.updateUserNull(userId);
    blockDao.updateUserNull(userId);
    userDao.deleteByPrimaryKey(userId);
    return true;
  }

  public User userWithDevices(String userId) throws Throwable {
    User user = userDao.selectByPrimaryKey(userId);
    if (user.getRoleId() == 0){
      user.setDevices(deviceDao.selectByUserId(null).toArray(new Device[0]));
//        user.setBlockIds(blockService.getBlockByUserId(null).toArray(new Block[0]));
    } else {
      user.setDevices(deviceDao.selectByUserId(userId).toArray(new Device[0]));
      user.setBlocks(blockDao.getBlocks(userId));
//      System.out.println(user.getDevices());
    }
    return user;
  }

  public User userWithBlocks(String userId){
      User user = userDao.selectByPrimaryKey(userId);
      user.setBlocks(blockDao.getBlocks(userId));
      return user;
  }

  public Map pUserWithBlocks(String userId){
    Map user = userDao.getPropertyUserById(userId);
    System.out.println(user.get("blocks"));
    user.put("blocks",blockDao.getBlocks(userId));
    return user;
  }

  public List<Map<String, Object>> getPropertyUser() {
    return userDao.getPropertyUser();
  }

  public Map getPropertyUserById(String id) {
    return userDao.getPropertyUserById(id);
  }

  public User getUserById(String userId) {
    return userDao.getUserById(userId);
  }

  public int addPropertyUser(Map map) {
    if (map.get("blockIds")==null){
      blockDao.updateBlockByMap(map);
    }
    return userDao.addPropertyUser(map);
  }

  public int updatePropertyUser(Map map) {
    return userDao.updatePropertyUser(map);
  }

  @Transactional
  public boolean modifyForPUser(User user) throws AlreadyException {
    for (long blockId:user.getBlockIds()
    ) {
      if (blockDao.selectByPrimaryKey(blockId).getUserId()!=null && !blockDao.selectByPrimaryKey(blockId).getUserId().equals(user.getId())){
        throw new AlreadyException("该区域块为其它用户管理！");
      }
    }
    assignBlocksByPUser(user);
    userDao.updatePUserByAdmin(user);
    return true;
  }

  private void assignBlocksByPUser(User user){
    blockDao.updateUserNull(user.getId());
    deviceDao.updateUserNull(user.getId());
    for (long blockId:user.getBlockIds()) {
      blockDao.updateUserByPrimaryKey(user.getId(), blockId);
      deviceDao.updateUserByBlockUserId(blockId, user.getId());
    }
  }

  public int delPropertyUser(String id) {
    return userDao.delPropertyUser(id);
  }

  public static class AlreadyException extends Exception {
    public AlreadyException(String message) {
      super(message);
    }
  }

  public boolean removePUserForBlocks(String id){
    blockDao.updateUserNull(id);
    deviceDao.updateUserNull(id);
    userDao.delPropertyUser(id);
    return true;
  }
}